﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel.DataAnnotations;
using Proggy.Web.Cms.Service;
using Proggy.Web.Cms.Controllers.FrontEnd;
using Proggy.Web.Cms.Membership;
using Proggy.Web.Cms.Repositories.ContentModel;
using Proggy.Web.Cms.Repositories.Published;
using Newtonsoft.Json;

namespace Proggy.Web.Cms.ContentModel
{
    /// <summary>
    /// Content model base interface
    /// </summary>
    public interface IContentModelBase
    {
        /// <summary>
        /// Id of content
        /// </summary>
        int Id { get; set; }

        /// <summary>
        /// Parent id or null
        /// </summary>
        int? ParentId { get; set; }

        /// <summary>
        /// True if has parent
        /// </summary>
        bool HasParent { get; }

        /// <summary>
        /// Order in parent container (where applicable)
        /// </summary>
        int OrderInParent { get; set; }

        /// <summary>
        /// An alias, which has to be unique and is mandatory but user inputted
        /// </summary>
        [MaxLength(64, ErrorMessage = "Unique alias cannot be longer than 64 characters in length")]
        [MinLength(6, ErrorMessage = "Unique alias is optional, however if it entered, it must be at least 6 characters long")]
        [RegularExpression("^[a-zA-Z0-9_]*$", ErrorMessage = "Unique alias can only contain uppercase letters, numbers and underscores (_)")]
        [Display(Name = "Unique alias")]  
        string UniqueAlias { get; set; }

        /// <summary>
        /// The content name
        /// </summary>
        [MaxLength(100)]
        [Display(Name = "Content name")]
        [Required(AllowEmptyStrings = false)]
        [MinLength(1)]
        string Name { get; set; }

        /// <summary>
        /// The url
        /// </summary>
        string Url { get; }

        /// <summary>
        /// The url slug
        /// </summary>
        [MaxLength(50)]
        [RegularExpression("^[a-z0-9-]*$", ErrorMessage = "Url can only contain lowercase letters, numbers and dashes (-)")]
        [Display(Name = "Url slug")]
        [Required(AllowEmptyStrings = false)]
        string UrlSlug { get; set; }

        /// <summary>
        /// The template used
        /// </summary>
        string Template { get; set; }

        /// <summary>
        /// The type alias
        /// </summary>
        string TypeAlias { get; set; }

        /// <summary>
        /// First created
        /// </summary>
        DateTime FirstCreated { get; set; }

        /// <summary>
        /// First created by
        /// </summary>
        ProggyMember FirstCreatedMember { get; }
        string FirstCreatedMemberUsername { get; set; }

        /// <summary>
        /// Last updated (if draft, then last save, if published then last published)
        /// </summary>
        DateTime LastUpdated { get; set; }

        /// <summary>
        /// Last updated by (if draft, then last save, if published then last published)
        /// </summary>
        ProggyMember LastUpdatedMember { get; }
        string LastUpdatedMemberUsername { get; set; }

        /// <summary>
        /// True if root node
        /// </summary>
        bool IsRoot { get; set; }

        /// <summary>
        /// Level in tree
        /// </summary>
        int LeveInTree { get; set; }


        IEnumerable<IContentModel> GetAbstractChildren();
        IEnumerable<TContentModel> GetTypedChildren<TContentModel>();
        IContentModel GetAbstractParent();
        TContentModel GetTypedParent<TContentModel>();
        object GetJsonObject();
        AvailableContentModel GetTypeData();        
        void OnAfterModelBinding(IContentCrudService repo);
        void OnAfterSuccesfulSave(IContentCrudService repo);
        void OnAfterSuccessfulPublish(IContentCrudService repo);
        void OnAfterSuccessfulTrash(IContentCrudService repo);
        void OnAfterSuccessfulMove(IContentCrudService repo);
        void OnAfterSuccessfulSort(IContentCrudService repo);
        FrontEndControllerBase GetControllerForContent();

        //[JsonIgnore]
        IPublishedContentRepository PublishedContentRepository { get; }

    }
}
